// 创建Three.js场景
var scene = new THREE.Scene();
// 创建摄像机，设置视角、宽高比和视距
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// 设置相机初始位置
camera.position.z = 10;
camera.position.y = 2;

// 定义道具类型
const POWERUP_TYPES = {
  SPEED: 'speed',
  SHIELD: 'shield',
  MAGNET: 'magnet',
  SLOW: 'slow'
};

// 道具效果持续时间（毫秒）
const POWERUP_DURATION = {
  [POWERUP_TYPES.SPEED]: 5000,
  [POWERUP_TYPES.SHIELD]: 3000,
  [POWERUP_TYPES.MAGNET]: 7000,
  [POWERUP_TYPES.SLOW]: 4000
};

// 道具效果状态
var powerupEffects = {
  [POWERUP_TYPES.SPEED]: false,
  [POWERUP_TYPES.SHIELD]: false,
  [POWERUP_TYPES.MAGNET]: false,
  [POWERUP_TYPES.SLOW]: false
};

// 道具剩余时间
var powerupTimers = {
  [POWERUP_TYPES.SPEED]: 0,
  [POWERUP_TYPES.SHIELD]: 0,
  [POWERUP_TYPES.MAGNET]: 0,
  [POWERUP_TYPES.SLOW]: 0
};

// 定义玩家对象及其属性
var player = {
  pos: new THREE.Vector3(0, 2, 10), // 初始位置
  vel: new THREE.Vector3(0, 0, 0),  // 初始速度
  acc: new THREE.Vector3(0, 0, 0),  // 初始加速度
  hit: false,                       // 是否被击中
  wantX: 0,                         // 目标X坐标
  jumping: false,                   // 是否跳跃中
  baseSpeed: 0.4,                   // 基础移动速度
  magnetRange: 5                    // 磁铁效果范围
}

// 设置场景移动速度
var panSpeed = player.baseSpeed;

// 设置重力向量
var gravity = new THREE.Vector3(0, -0.1, 0);

// 创建WebGL渲染器，启用抗锯齿
var renderer = new THREE.WebGLRenderer({ antialias: true });
// 设置场景背景颜色
scene.background = new THREE.Color('#001d45');
// 设置渲染器尺寸为窗口大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 将渲染器添加到页面
document.body.appendChild(renderer.domElement);

// 监听窗口大小变化，调整渲染尺寸
window.addEventListener("resize", () => {
  renderer.setSize(window.innerWidth, window.innerHeight);
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
});

// 创建地板
var floorgeo = new THREE.BoxGeometry(30, 0.5, 500);
var floormat = new THREE.MeshLambertMaterial({ color: 0x0000aa });
var floormesh = new THREE.Mesh(floorgeo, floormat);
scene.add(floormesh);

// 创建天花板
var ceilinggeo = new THREE.BoxGeometry(30, 0.5, 500);
var ceilingmat = new THREE.MeshLambertMaterial({ color: 0x0000aa });
var ceilingmesh = new THREE.Mesh(ceilinggeo, ceilingmat);
scene.add(ceilingmesh);
ceilingmesh.position.y = 15;

// 添加场景雾效，增强距离感
scene.fog = new THREE.Fog('#001d45', 10, 300);

// 创建障碍物数组
var cones = [];
for (var i = 0; i < 500; i++) {
  // 随机决定障碍物高度
  let h = 5;
  if (Math.random() <= 0.33) h = 10;
  
  // 创建圆锥体作为障碍物
  var geometry = new THREE.ConeGeometry(3, h, 10);
  var material = new THREE.MeshBasicMaterial({ color: '#fcba03' });
  var cone = new THREE.Mesh(geometry, material);
  cones.push(cone);
  scene.add(cone);
  
  // 设置障碍物位置
  cone.position.z = -i * 30 - 30;
  cone.originalZ = -i * 30 - 30;
  cone.h = h;
  
  // 50%概率将障碍物放在天花板上
  if (Math.random() <= 0.5) {
    cone.position.y = 15;
    cone.rotation.z = Math.PI;
  }
  
  // 随机决定障碍物的X坐标位置（左、中、右）
  let dirR = Math.random();
  if (dirR <= .33) cone.position.x = -7.5;
  if (dirR >= .66) cone.position.x = 7.5;
}

// 添加半球光源
var light = new THREE.HemisphereLight(0xffffbb, 0x080820, 1);
scene.add(light);

// 添加点光源
var light = new THREE.PointLight(0xff0000, 1, 100);
light.position.set(10, 7.5, player.pos.z);
scene.add(light);

// 创建道具数组
var powerups = [];

// 创建道具几何体和材质
var powerupGeometry = new THREE.SphereGeometry(1, 8, 8);
var powerupMaterials = {
  [POWERUP_TYPES.SPEED]: new THREE.MeshBasicMaterial({ color: 0x00ff00 }),    // 绿色
  [POWERUP_TYPES.SHIELD]: new THREE.MeshBasicMaterial({ color: 0x0000ff }),   // 蓝色
  [POWERUP_TYPES.MAGNET]: new THREE.MeshBasicMaterial({ color: 0xff00ff }),   // 紫色
  [POWERUP_TYPES.SLOW]: new THREE.MeshBasicMaterial({ color: 0xffff00 })      // 黄色
};

// 创建道具生成函数
function createPowerup(type, position) {
  var powerup = new THREE.Mesh(powerupGeometry, powerupMaterials[type]);
  powerup.position.copy(position);
  powerup.type = type;
  powerup.collected = false;
  powerups.push(powerup);
  scene.add(powerup);
  return powerup;
}

// 应用道具效果
function applyPowerup(type) {
  powerupEffects[type] = true;
  powerupTimers[type] = POWERUP_DURATION[type];
  
  switch(type) {
    case POWERUP_TYPES.SPEED:
      panSpeed = player.baseSpeed * 1.5;
      break;
    case POWERUP_TYPES.SHIELD:
      player.hit = false;
      break;
    case POWERUP_TYPES.SLOW:
      panSpeed = player.baseSpeed * 0.5;
      break;
  }

  // 更新UI显示
  updatePowerupUI(type);
}

// 更新道具UI显示
function updatePowerupUI(type) {
  // 移除已存在的相同类型道具UI
  const existingPowerup = document.querySelector(`.powerup-indicator.${type}`);
  if (existingPowerup) {
    existingPowerup.remove();
  }

  const powerupElement = document.createElement('div');
  powerupElement.className = `powerup-indicator ${type}`;
  powerupElement.style.position = 'fixed';
  powerupElement.style.top = '50px';
  powerupElement.style.right = '20px';
  powerupElement.style.padding = '10px';
  powerupElement.style.backgroundColor = `rgba(${type === POWERUP_TYPES.SPEED ? '0,255,0' : type === POWERUP_TYPES.SHIELD ? '0,0,255' : type === POWERUP_TYPES.MAGNET ? '255,0,255' : '255,255,0'},0.5)`;
  powerupElement.style.borderRadius = '5px';
  powerupElement.style.minWidth = '120px';
  powerupElement.style.textAlign = 'center';
  powerupElement.style.fontFamily = 'Arial, sans-serif';
  powerupElement.style.fontSize = '14px';
  powerupElement.style.fontWeight = 'bold';
  powerupElement.style.color = '#ffffff';
  powerupElement.style.textShadow = '1px 1px 2px rgba(0,0,0,0.5)';
  powerupElement.style.display = 'flex';
  powerupElement.style.flexDirection = 'column';
  powerupElement.style.gap = '5px';
  
  const nameElement = document.createElement('div');
  nameElement.textContent = type.toUpperCase();
  powerupElement.appendChild(nameElement);
  
  const timerElement = document.createElement('div');
  timerElement.className = 'powerup-timer';
  timerElement.style.fontSize = '12px';
  powerupElement.appendChild(timerElement);
  
  document.body.appendChild(powerupElement);
}

// 渲染函数 - 游戏主循环
var render = () => {
  requestAnimationFrame(render);

  let dead = false;
  
  // 更新所有障碍物位置并检测碰撞
  for (var i = 0; i < cones.length; i++) {
    // 障碍物向玩家方向移动
    cones[i].position.z += panSpeed;

    // 计算玩家与障碍物的距离
    let dist = player.pos.distanceTo(cones[i].position);
    let size = 3;
    if (cones[i].h > 5) size = 5;
    
    // 检测碰撞
    if (Math.floor(dist) < size && !player.hit && !powerupEffects[POWERUP_TYPES.SHIELD]) {
      dead = true;
      panSpeed = player.baseSpeed - 0.001;
      // 更新上一次分数
      $(".lastScore").html("Last score: " + Math.floor(cones[0].position.z + 30))
      // 显示失败提示
      $(".lose").addClass("show");
      // 1秒后隐藏失败提示
      setTimeout(() => { $(".lose").removeClass("show"); }, 1000)
    }
  }

  // 随时间增加游戏速度
  panSpeed += 0.0001;

  // 如果发生碰撞
  if (dead) {
    player.hit = true;
    // 1秒后重置hit状态
    setTimeout(() => { player.hit = false; }, 1000)
    // 将所有障碍物和道具重置到初始位置
    for (var i = 0; i < cones.length; i++) {
      this.tl = new TimelineMax();
      this.tl.to(cones[i].position, 1, { z: cones[i].originalZ });
    }
    // 清除所有道具
    for (let i = powerups.length - 1; i >= 0; i--) {
      scene.remove(powerups[i]);
    }
    powerups.length = 0;
  }

  // 应用重力到加速度
  player.acc.add(gravity);

  // 更新玩家速度和位置
  player.vel.add(player.acc);
  player.pos.add(player.vel);
  // 重置加速度
  player.acc.set(0, 0, 0);

  // 平滑过渡到目标X位置
  if (player.wantX > player.pos.x) player.pos.x++;
  if (player.wantX < player.pos.x) player.pos.x--;

  // 检测天花板和地板碰撞，停止跳跃
  if (player.pos.y >= 13 && camera.rotation.z !== 0 || player.pos.y <= 2 && camera.rotation.z == 0) {
    player.jumping = false;
    player.vel.y = 0;
  }

  // 限制玩家移动范围
  player.pos.clamp(new THREE.Vector3(-7.5, 2, 10), new THREE.Vector3(7.5, 13, 10));

  // 更新光源位置跟随玩家
  light.position.set(10, 7.5, player.pos.z);
  // 更新相机位置跟随玩家
  camera.position.set(player.pos.x, player.pos.y, player.pos.z);

  // 更新得分显示
  $(".score").html("Score: " + Math.floor(cones[0].position.z + 30));

  // 更新道具位置和检测碰撞
  for (let i = powerups.length - 1; i >= 0; i--) {
    const powerup = powerups[i];
    if (!powerup.collected) {
      powerup.position.z += panSpeed;
      
      // 检测道具碰撞
      let dist = player.pos.distanceTo(powerup.position);
      
      // 磁铁效果时增加收集范围
      let collectRange = powerupEffects[POWERUP_TYPES.MAGNET] ? player.magnetRange : 2;
      
      if (dist < collectRange) {
        powerup.collected = true;
        scene.remove(powerup);
        applyPowerup(powerup.type);
        powerups.splice(i, 1);
      }
      
      // 移除超出范围的道具
      if (powerup.position.z > player.pos.z + 20) {
        scene.remove(powerup);
        powerups.splice(i, 1);
      }
    }
  }

  // 随机生成道具（每300单位距离生成一个）
  if (Math.random() < 0.03 && powerups.length < 5) {  // 3%的概率生成道具，最多同时存在5个
    const types = Object.values(POWERUP_TYPES);
    const randomType = types[Math.floor(Math.random() * types.length)];
    
    // 使用与障碍物相同的X轴位置逻辑
    let randomX = 0; // 默认在中间
    const dirR = Math.random();
    if (dirR <= 0.33) randomX = -7.5;  // 左边
    if (dirR >= 0.66) randomX = 7.5;   // 右边
    
    const randomY = Math.random() * 11 + 2;  // 2 到 13 之间
    // 在玩家前方远处生成道具（与障碍物生成位置相似）
    createPowerup(randomType, new THREE.Vector3(randomX, randomY, player.pos.z - 300));
  }

  // 更新道具时间
  Object.keys(powerupTimers).forEach(type => {
    if (powerupEffects[type]) {
      powerupTimers[type] -= 16.67; // 约60帧每秒
      
      // 更新倒计时显示
      const timerElement = document.querySelector(`.powerup-indicator.${type} .powerup-timer`);
      if (timerElement) {
        const secondsLeft = Math.max(0, Math.ceil(powerupTimers[type] / 1000));
        timerElement.textContent = `剩余: ${secondsLeft}秒`;
      }
      
      // 检查是否结束
      if (powerupTimers[type] <= 0) {
        powerupEffects[type] = false;
        powerupTimers[type] = 0;
        
        // 重置效果
        if (type === POWERUP_TYPES.SPEED || type === POWERUP_TYPES.SLOW) {
          panSpeed = player.baseSpeed;
        }
        
        // 移除UI显示
        const powerupElement = document.querySelector(`.powerup-indicator.${type}`);
        if (powerupElement) {
          powerupElement.remove();
        }
      }
    }
  });

  // 渲染场景
  renderer.render(scene, camera);
}

// 启动渲染循环
render();

// 添加键盘控制监听
document.addEventListener('keyup', (e) => {
  // 上箭头键 - 重力反转
  if (e.code === "ArrowUp") {
    gravity.y *= -1;  // 反转重力方向
    player.vel.y = 0; // 重置垂直速度
    this.tl = new TimelineMax();
    // 相机旋转动画
    if (camera.rotation.z == 0) {
      this.tl.to(camera.rotation, .2, { z: Math.PI });
    } else {
      this.tl.to(camera.rotation, .2, { z: Math.PI * 2 });
      this.tl.to(camera.rotation, 0, { z: 0 });
    }
  }
  
  // 正常重力状态下的控制
  if (camera.rotation.z == 0) {
    // 空格键 - 跳跃
    if (e.code === "Space" && !player.jumping) {
      player.jumping = true;
      player.acc.y += 1.2;
    }
    // 左右箭头 - 水平移动
    if (e.code === "ArrowLeft") {
      if (player.wantX >= 0) player.wantX -= 7.5;
    }
    if (e.code === "ArrowRight") {
      if (player.wantX <= 0) player.wantX += 7.5;
    }
  } else {
    // 反重力状态下的控制（操作反向）
    if (e.code === "Space" && !player.jumping) {
      player.jumping = true;
      player.acc.y -= 1.2;
    }
    if (e.code === "ArrowRight") {
      if (player.wantX >= 0) player.wantX -= 7.5;
    }
    if (e.code === "ArrowLeft") {
      if (player.wantX <= 0) player.wantX += 7.5;
    }
  }
});